package com.qf.index;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;
import lombok.Data;

import java.io.File;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Xxmu {

    /**
     * 整理新乡医学院SCI论文榜，这里使用通义规范了部门的名称，但还没有作者的中文名称。
     * 贾新志 2025.03.23
     */

    public static void main(String[] args) throws SQLException {
        String newDataName = "scholar_25_02.";
        String xxmuWosTable = newDataName + "xxmu_wos_talbe_0323";
        String recordTable = newDataName + "wos_updata_record_table_0321";
        String keyWordSumTable = newDataName + "key_word_sum_0124_2";
        String jourMergeTable = newDataName + "basic_jour_merge";
        String wordAndCodeSetMapTable = newDataName + "word_and_code_set_map";
        String meshTable = newDataName + "help_mesh_tree_gcr_0615";
        String htLocationChinaTable = newDataName + "ht_location_china";
        String basicHospUnivDeptTable = newDataName + "basic_hosp_or_univ_dept";


        String path = "C:\\临时文件\\2025_03\\正常字段";
        String user = "Bearer sk-06a0675779c944b6a4d5b893cb3cc89a";
        String kw = "AD=(xinxiang Medical University) OR AD=(Xinxiang Med Univ) OR AD=(xinxiang Medical College)";
        boolean hospPriority = true;
        saveCsvSplitWos(path, recordTable, xxmuWosTable, jourMergeTable, wordAndCodeSetMapTable, meshTable, keyWordSumTable, htLocationChinaTable, basicHospUnivDeptTable, kw, hospPriority, user);


    }

    public static void saveCsvSplitWos(String path, String recordTable, String xxmuWosTable, String jourMergeTable, String wordAndCodeSetMapTable, String meshTable, String keyWordSumTable, String htLocationChinaTable, String basicHospUnivDeptTable, String kw, boolean hospPriority, String user) throws SQLException {
        Db.use().execute("truncate table " + xxmuWosTable);
        Db.use().execute("truncate table " + recordTable);
        Map<String, En.JidInfo> zuHeAndJidInfoMap = UtToBib.getZuHeAndJidInfoMap(jourMergeTable, "id", "nc_nlmid_list`,`jcr_quartile`,`cite_score`,`jcr_if`,`zky_dalei`,`nc_nlm_title_abbreviation`,`ncbi_mesh`,`ncbi_subject`,`zky_subject`,`zuhe");
        Map<String, Set<Integer>> wordAndCodeSetMap = Drug.getWordAndCodeSetMap(wordAndCodeSetMapTable, "id", "word`,`code_set", "");
        Map<String, String> md5Map = new ConcurrentHashMap<>();
        Map<String, String> reKwMap = cList.getReKwMap();
        Map<String, String> keyWordAndMeshMap = new ConcurrentHashMap<>();
        Map<String, String> originalAndMeshMap = new ConcurrentHashMap<>();
        Map<String, String> lowerToUpperMap = new ConcurrentHashMap<>();
        ReadKw.readMesh(meshTable, "id", "meshName`,`entryTerms", md5Map, keyWordAndMeshMap, originalAndMeshMap, reKwMap, lowerToUpperMap);
        Set<String> originalSet = Bibliometric.getKeyWordAndStandardMap(keyWordSumTable, lowerToUpperMap, "id", "is_cn`,`sum`,`key_word", originalAndMeshMap);
//        Map<String, String> keyWordAndStandardMap = Bibliometric.getKeyWordAndStandardMap(keyWordSumTable, keyWordAndMeshMap, md5Map, reKwMap, "id", "is_cn`,`sum`,`key_word");
        Set<String> chinaSet = cList.chinaSet();
        Set<String> citySet = new HashSet<>();
        Set<String> subjectSet = cList.getSubjectSet();
        Set<String> provCitySet = Dept.getProvCitySet(htLocationChinaTable, "id", "prov`,`name", citySet);
        Map<String, String> standardMap = new ConcurrentHashMap<>();
        standardMap.put("department medical", "Department Medical");
        Map<String, Set<String>> deptAndInfoSetMap = new ConcurrentHashMap<>();
        Map<String, Integer> deptAndSumMap = new ConcurrentHashMap<>();
        Map<String, Set<String>> unitAndInfoSetMap = new ConcurrentHashMap<>();
        Map<String, Integer> unitAndSumMap = new ConcurrentHashMap<>();
        Map<String, String> countryMap = cList.getCountryMap();
        Set<String> acadSet = uSet.getAcadSet();
        Set<String> centerSet = uSet.getCenterSet();
        Set<String> collSet = uSet.getCollSet();
        Set<String> hospSet = uSet.getHospSet();
        Set<String> univSet = uSet.getUnivSet();
        Set<String> removeSet = uSet.getRemoveSet();
        Set<String> dellSet = uSet.getDellSet();
        Set<String> toDeptSet = uSet.toDept();
        Map<String, En.FuDanStemEdu> fuDanStemEduMap = Guidelines.getFuDanStemEduMap(basicHospUnivDeptTable, "id", "info`,`fudan`,`stem`,`edu");
        Set<String> pinYinSet = PmUnit.getPinYinSet();
        Set<String> early2020 = Institution.getEarly2020();
        Set<String> early2021 = Institution.getEarly2021();
        Set<String> early2023 = Institution.getEarly2023();
        Set<String> early2024 = Institution.getEarly2024();
        Set<String> utSet = new HashSet<>();
        Set<String> univNameSet = new HashSet<>();
        univNameSet.add(" univ");
        univNameSet.add("univ ");
        univNameSet.add("sch med");
        univNameSet.add("coll med");
        univNameSet.add("med coll");

        Set<String> hospNameSet = new HashSet<>();
        hospNameSet.add(" hosp");
        hospNameSet.add("hosp ");
        hospNameSet.add("affiliated");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<File> files = FileUtil.loopFiles(path);
        for (File file : files) {
            String filePath = file.getAbsolutePath();
            if (!filePath.toUpperCase().endsWith(".TXT") || !new File(filePath).exists()) {
                continue;
            }
            int sum = 0;
            String str = FileUtil.readUtf8String(filePath);
            String[] line = str.split("\n");
            for (int i = 0; i < line.length; i++) {
                String s = line[i];
                if (i == 0 && s.startsWith("\uFEFFnull")) {
                    System.out.println("错误的开头：" + s);
                }
                s = (i == 0 && s.startsWith("\uFEFFnullnullnullnullJ\t")) ? s.substring("\uFEFFnullnullnullnull".length()) : s;
                String[] split = s.split("\t");
                if (split.length != 71) {
                    System.out.println("--不相等，可能出现了错行或者WOS的格式改变，这是本条的源数据：" + s);
                    continue;
                }
                boolean bool = true;
                if (i == 0 && s.startsWith("\uFEFFPT\tAU")) {
                    if ("PT".equals(split[0].trim()) && "AU".equals(split[1]) && "BA".equals(split[2]) && "BE".equals(split[3]) && "GP".equals(split[4]) && "AF".equals(split[5]) && "BF".equals(split[6]) && "CA".equals(split[7]) && "TI".equals(split[8]) &&
                            "SO".equals(split[9]) && "SE".equals(split[10]) && "BS".equals(split[11]) && "LA".equals(split[12]) && "DT".equals(split[13]) && "CT".equals(split[14]) && "CY".equals(split[15]) && "CL".equals(split[16]) && "SP".equals(split[17]) &&
                            "HO".equals(split[18]) && "DE".equals(split[19]) && "ID".equals(split[20]) && "AB".equals(split[21]) && "C1".equals(split[22]) && "C3".equals(split[23]) && "RP".equals(split[24]) && "EM".equals(split[25]) && "RI".equals(split[26]) &&
                            "OI".equals(split[27]) && "FU".equals(split[28]) && "FP".equals(split[29]) && "FX".equals(split[30]) && "CR".equals(split[31]) && "NR".equals(split[32]) && "TC".equals(split[33]) && "Z9".equals(split[34]) && "U1".equals(split[35]) &&
                            "U2".equals(split[36]) && "PU".equals(split[37]) && "PI".equals(split[38]) && "PA".equals(split[39]) && "SN".equals(split[40]) && "EI".equals(split[41]) && "BN".equals(split[42]) && "J9".equals(split[43]) && "JI".equals(split[44]) &&
                            "PD".equals(split[45]) && "PY".equals(split[46]) && "VL".equals(split[47]) && "IS".equals(split[48]) && "PN".equals(split[49]) && "SU".equals(split[50]) && "SI".equals(split[51]) && "MA".equals(split[52]) && "BP".equals(split[53]) &&
                            "EP".equals(split[54]) && "AR".equals(split[55]) && "DI".equals(split[56]) && "DL".equals(split[57]) && "D2".equals(split[58]) && "EA".equals(split[59]) && "PG".equals(split[60]) && "WC".equals(split[61]) && "WE".equals(split[62]) &&
                            "SC".equals(split[63]) && "GA".equals(split[64]) && "PM".equals(split[65]) && "OA".equals(split[66]) && "HC".equals(split[67]) && "HP".equals(split[68]) && "DA".equals(split[69]) && "UT".equals(split[70].trim())) {
                        continue;
                    } else {
                        System.out.println("--不相等，可能出现了错行或者WOS的格式改变，这是本条的源数据：" + s);
                        bool = false;
                    }
                }
                String ut = split[70].toUpperCase().trim().replace("：", ":").replaceAll("[^A-Za-z0-9:]", "");
                sum = (bool && ut.startsWith("WOS:") && ut.length() == 19) ? (sum + 1) : sum;
                if (bool && ut.startsWith("WOS:") && ut.length() == 19 && !utSet.contains(ut)) {
                    utSet.add(ut);
                    String keyword = split[19];
                    String title = split[8];
                    String abText = split[21];
                    String j9 = split[43];
                    String so = split[9];
                    String py = split[46];
                    int year = NumberUtil.isInteger(py) ? Integer.parseInt(py.trim()) : 1900;
                    List<En.C1Auth> c1List = new ArrayList<>();
                    boolean isOrder = Utils.getC1ListSort(split[22], pinYinSet, c1List);
                    List<En.C1Auth> rpList = Utils.getRpListSort(split[24], isOrder, pinYinSet);
                    List<En.C1Auth> rpChangeC1 = ChangeRp.rpChangeC1(c1List, rpList);
                    String di = Utils.dellEnd(split[56]);
                    String v = split[47];
                    String ii = split[48];
                    String b = split[53];
                    String e = split[54];
                    String jour = Utils.toTitleCase((j9.length() > 2 && !j9.endsWith("+") ? j9 : so));
                    // 格式：Anticancer Drugs. 2021 Aug 1;32(7):717-726. doi: 10.1097/CAD.0000000000001050.
                    String info = jour + ". " + (year + ";") + (null == v ? "" : v) + (null == ii ? "" : "(" + ii + "):") + (null == b ? "" : b) + (null == e || e.isEmpty() ? ". " : "-" + e + ". ") + (di.length() > 6 ? ("doi: " + di + ". ") : "");

                    String sn = split[40];
                    String ei = split[41];
                    En.JidInfo jidInfo = new En.JidInfo();
                    if (!sn.isEmpty() && !j9.isEmpty() && zuHeAndJidInfoMap.containsKey(Institution.re("ISSN" + sn + j9))) {
                        jidInfo = zuHeAndJidInfoMap.get(Institution.re("ISSN" + sn + j9));
                    } else if (!sn.isEmpty() && !so.isEmpty() && zuHeAndJidInfoMap.containsKey(Institution.re("ISSN" + sn + so))) {
                        jidInfo = zuHeAndJidInfoMap.get(Institution.re("ISSN" + sn + so));
                    } else if (!ei.isEmpty() && !j9.isEmpty() && zuHeAndJidInfoMap.containsKey(Institution.re("ISSN" + ei + j9))) {
                        jidInfo = zuHeAndJidInfoMap.get(Institution.re("ISSN" + ei + j9));
                    } else if (!ei.isEmpty() && !so.isEmpty() && zuHeAndJidInfoMap.containsKey(Institution.re("ISSN" + ei + so))) {
                        jidInfo = zuHeAndJidInfoMap.get(Institution.re("ISSN" + ei + so));
                    }
                    List<En.CategoryAndInfo> categoryAndInfoList = Drug.getDrug(title, keyword, abText, wordAndCodeSetMap);

                    Set<InfoDept> deptSet = new HashSet<>();
                    for (En.C1Auth c1Auth : c1List) {
                        String full = c1Auth.getFull().isEmpty() ? c1Auth.getInfo() : c1Auth.getFull();
                        if (Institution.doCheck(full, Institution.checkGrammar(kw))) {
                            String content = "发表SCI论文一般都会署名作者所属的单位和部门，请检查论文作者信息：\"" + full + "\" 中是否包含新乡医学院附属的医院或下属的部门名称，并将其与已知的52个标准附属医院或下属部门名称进行匹配，比如：\"Xinxiang Medical University, Henan Key Laboratories Medical " +
                                    "Tissue Regenerat, Xinxiang 453003, Henan, People's Republic of China\" 从其作者信息可以知道其部门是：河南省医学组织再生重点实验室，再与标准附属医院或部门名称匹配，则可以返回：河南省医用组织再生重点实验室，请据此原则进行匹配，如果匹配成功，请返回标准名称，如果不能完全匹配成功，而是近似匹配成功的，" +
                                    "请在匹配的名称上加上英文的方括号，如果有多个可能的匹配项，选择最接近的一个。若无任何名称匹配，则将识别到的附属医院或下属部门的名称加上英文的括号后返回。可以参考的标准名称清单：网络与信息中心 - 图书馆（档案馆） - 期刊社 - 临床医学学部 - 人文社会科学学部 - 药学学部 - 峻极书院 - " +
                                    "弘毅书院 - 基础医学院 - 公共卫生学院 - 药学院 - 医学技术学院 - 护理学院 - 卫生健康管理学院 - 法医学院 - 生命科学技术学院 - 心理学院 - 外语学院 - 医学工程学院 - 马克思主义学院 - 医学人文学院 - 体育学院 - 国际教育学院 - 继续教育学院 - 河南省心理咨询中心 - 河南省神经病学研究所 - " +
                                    "河南省科技期刊研究中心 - 健康中原研究院 - 新乡医学院结核病研究所 - 新乡医学院心血管疾病研究所 - 河南省高等医学教育发展研究中心 - 河南省分子诊断与医学检验技术协同创新中心 - 精神疾病中西医结合临床医学中心 - 新乡医学院组织工程与再生临床医学中心 - 河南省生物精神病学重点实验室 - " +
                                    "河南省医用组织再生重点实验室 - 河南省神经修复重点实验室 - 河南省免疫与靶向药物重点实验室 - 精神神经医学研究院 - 第一附属医院 - 第二附属医院 - 第三附属医院 - 附属中心医院 - 附属人民医院 - 附属濮阳市油田总医院 - 附属焦作市人民医院 - 附属濮阳市人民医院 - 附属濮阳市安阳地区医院 - " +
                                    "附属开封市中心医院 - 附属郑州市第一人民医院 - 附属郑州市第七人民医院 - 附属安阳市人民医院。请返回标准的JSON的数据格式：{\"name\":\"\"}";
                            String api = TongYiApi.api(content, user);
                            Matcher matcher = Pattern.compile("\"name\"\\s*:\\s*\"([^\"]*)\"").matcher(api);
                            if (matcher.find()) {
                                String trim = matcher.group(1).trim();
                                if (trim.length() > 2) {
                                    InfoDept infoDept = new InfoDept();
                                    infoDept.setAuthList(c1Auth.getAuthList());
                                    infoDept.setInfo(full);
                                    infoDept.setDept(trim);
                                    deptSet.add(infoDept);
                                }
                            }
                        }
                    }

                    Guidelines.setC1List(c1List, standardMap, acadSet, centerSet, collSet, hospSet, univSet, removeSet, countryMap, deptAndSumMap, dellSet, chinaSet, provCitySet, citySet, subjectSet, deptAndInfoSetMap, unitAndInfoSetMap, unitAndSumMap, toDeptSet, fuDanStemEduMap);
                    Guidelines.setC1List(rpChangeC1, standardMap, acadSet, centerSet, collSet, hospSet, univSet, removeSet, countryMap, deptAndSumMap, dellSet, chinaSet, provCitySet, citySet, subjectSet, deptAndInfoSetMap, unitAndInfoSetMap, unitAndSumMap, toDeptSet, fuDanStemEduMap);

                    List<List<String>> kwListList = new ArrayList<>();
                    if (!keyword.isEmpty()) {
                        List<String> kwList = new ArrayList<>(Arrays.asList(keyword.split("; ")));
                        ReadKw.addListList(originalAndMeshMap, kwList, kwListList, lowerToUpperMap);
                    }

                    List<List<String>> tiListList = new ArrayList<>();
                    List<String> tiKeyList = title.length() > 4 ? ReadKw.getTiKey(title, originalSet, lowerToUpperMap) : new ArrayList<>();
                    ReadKw.addListList(originalAndMeshMap, tiKeyList, tiListList, lowerToUpperMap);
                    ReadKw.addAbbSet(title, tiListList, lowerToUpperMap);

                    List<List<String>> abListList = new ArrayList<>();
                    List<String> abKeySet = abText.length() > 10 ? ReadKw.getAbKey(abText, originalSet, lowerToUpperMap) : new ArrayList<>();
                    ReadKw.addListList(originalAndMeshMap, abKeySet, abListList, lowerToUpperMap);
                    ReadKw.addAbbSet(abText, abListList, lowerToUpperMap);

                    int isEarly = 0;
                    if ("2020".equals(py) && (early2020.contains(j9) || early2020.contains(so))) {
                        isEarly = 1;
                    } else if ("2021".equals(py) && (early2021.contains(j9) || early2021.contains(so))) {
                        isEarly = 1;
                    } else if ("2023".equals(py) && (early2023.contains(j9) || early2023.contains(so))) {
                        isEarly = 1;
                    } else if ("2024".equals(py) && (early2024.contains(j9) || early2024.contains(so))) {
                        isEarly = 1;
                    }

                    List<Institution.SortInfo> c1SortInfoList = Institution.addSortInfoList(Institution.getC1List(split[22]), kw, univNameSet, hospNameSet, hospPriority);
                    List<Institution.SortInfo> rpSortInfoList = Institution.addSortInfoList(Institution.getRpList(split[24]), kw, univNameSet, hospNameSet, hospPriority);
                    int c1 = 0;
                    int c1Univ = 0;
                    int c1Hosp = 0;
                    for (Institution.SortInfo sortInfo : c1SortInfoList) {
                        int order = sortInfo.getOrder();
                        if (order == 0) {
                            c1 = 1;
                            c1Univ = sortInfo.getUniv() ? 1 : c1Univ;
                            c1Hosp = sortInfo.getHosp() ? 1 : c1Hosp;
                        } else {
                            c1 = c1 == 0 ? 2 : c1;
                            c1Univ = sortInfo.getUniv() && c1Univ == 0 ? 2 : c1Univ;
                            c1Hosp = sortInfo.getHosp() && c1Hosp == 0 ? 2 : c1Hosp;
                        }
                    }
                    // c1和rp均有三种值，分别是0、1、2，0为不包含，1为第一作者，2为参与作者。c1又分为c1、c1Univ、c1Hosp三种，rp又分为rp、rpUniv、rpHosp三种。
                    int rp = 0;
                    int rpUniv = 0;
                    int rpHosp = 0;
                    for (Institution.SortInfo sortInfo : rpSortInfoList) {
                        int order = sortInfo.getOrder();
                        if (order == 0) {
                            rp = 1;
                            rpUniv = sortInfo.getUniv() ? 1 : rpUniv;
                            rpHosp = sortInfo.getHosp() ? 1 : rpHosp;
                        } else {
                            rp = rp == 0 ? 2 : rp;
                            rpUniv = sortInfo.getUniv() && rpUniv == 0 ? 2 : rpUniv;
                            rpHosp = sortInfo.getHosp() && rpHosp == 0 ? 2 : rpHosp;
                        }
                    }

                    try {
                        Db.use().insert(Entity.create(xxmuWosTable).set("PT", split[0].trim()).set("AU", split[1]).set("BA", split[2]).set("BE", split[3]).set("GP", split[4]).set("AF", split[5]).set("BF", split[6]).set("CA", split[7]).set("TI", split[8])
                                .set("SO", split[9]).set("SE", split[10]).set("BS", split[11]).set("LA", split[12]).set("DT", split[13]).set("CT", split[14]).set("CY", split[15]).set("CL", split[16]).set("SP", split[17]).set("HO", split[18])
                                .set("DE", split[19]).set("ID", split[20]).set("AB", split[21]).set("C1", split[22]).set("C3", split[23]).set("RP", split[24]).set("EM", split[25]).set("RI", split[26]).set("OI", split[27]).set("FU", split[28])
                                .set("FP", split[29]).set("FX", split[30]).set("CR", split[31]).set("NR", split[32]).set("TC", split[33]).set("Z9", split[34]).set("U1", split[35]).set("U2", split[36]).set("PU", split[37]).set("PI", split[38])
                                .set("PA", split[39]).set("SN", split[40]).set("EI", split[41]).set("BN", split[42]).set("J9", split[43]).set("JI", split[44]).set("PD", split[45]).set("PY", split[46]).set("VL", split[47]).set("IS", split[48])
                                .set("PN", split[49]).set("SU", split[50]).set("SI", split[51]).set("MA", split[52]).set("BP", split[53]).set("EP", split[54]).set("AR", split[55]).set("DI", split[56]).set("DL", split[57]).set("D2", split[58])
                                .set("EA", split[59]).set("PG", split[60]).set("WC", split[61]).set("WE", split[62]).set("SC", split[63]).set("GA", split[64]).set("PM", split[65]).set("OA", split[66]).set("HC", split[67]).set("HP", split[68])
                                .set("DA", split[69]).set("UT", split[70].trim())
                                .set("ti_key", JSONUtil.toJsonStr(tiListList))
                                .set("ab_key", JSONUtil.toJsonStr(abListList))
                                .set("kw_key", JSONUtil.toJsonStr(kwListList))
                                .set("zky_dalei", jidInfo.getZkyDaLei())
                                .set("jcr_if", jidInfo.getJcrIf())
                                .set("jid", jidInfo.getJid())
                                .set("c1_au", JSONUtil.toJsonStr(c1List))
                                .set("rp_au", JSONUtil.toJsonStr(rpChangeC1))
                                .set("is_cns", Utils.is6DaJournals("", "", so, j9))
                                .set("nlmId", jidInfo.getNlmId())
                                .set("cite_score", jidInfo.getCiteScore())
                                .set("jcr_quartile", jidInfo.getJcrQuartile())
                                .set("fund_list", JSONUtil.toJsonStr(ReadUt.getFundList(split[29])))
                                .set("drug_gene_pathway_disease", JSONUtil.toJsonStr(categoryAndInfoList))
                                .set("info", Fusion.reInfo(info))
                                .set("ncbi_subject", jidInfo.getNcbiSubject())
                                .set("ncbi_journal", jidInfo.getNcbiJournal())
                                .set("ncbi_mesh", jidInfo.getNcbiMesh())
                                .set("early_warning", isEarly)
                                .set("dept", JSONUtil.toJsonStr(deptSet))
                                .set("c1_code", c1).set("c1_univ_code", c1Univ).set("c1_hosp_code", c1Hosp).set("rp_code", rp).set("rp_univ_code", rpUniv).set("rp_hosp_code", rpHosp).set("datetime", LocalDateTime.now())
                        );
                    } catch (SQLException ee) {
                        ee.printStackTrace();
                    }
                }
            }
            try {
                Db.use().insert(Entity.create(recordTable).set("path", filePath).set("sum", utSet.size()).set("date", LocalDateTime.now()));
                System.out.println("\033[31;1m" + format.format(new Date()) + " 累计插入： " + utSet.size() + " 条。文件：" + filePath + " ，本文件内含有 " + sum + " 条" + Utils.printMemoryStr() + "\033[0m");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @Data
    public static class InfoDept {
        private List<String> authList = new ArrayList<>();
        private String info = "";
        private String dept = "";
    }


}
